#include <iostream>

// C style enum
// Red = 0, Green = 1, Blue = 2;
enum Color { Red, Green, Blue };

// C++ style enum class
enum class Color2 { Red, Green, Blue };

// C++ style enum class with specified underlying type
enum class Color3 : unsigned char { Red, Green, Blue };

// POD
struct Book {
  char title[50];
  int pages;
  int year;
};

union Variant {
  int i;
  double d;
};

void use_enum1();
void use_enum2();
void pod_use();
void union_use();

int main(int argc, char *argv[]) {
  std::cout << "==== ch02 p03 ====" << std::endl;
  printf("---- use_enum1() ----\n");
  use_enum1();
  printf("---- use_enum2() ----\n");
  use_enum2();
  printf("---- pod_use1() ----\n");
  pod_use();
  printf("---- union_use() ----\n");
  union_use();
  return 0;
}

void use_enum1() {
  Color c1 = Red;
  Color2 c2 = Color2::Red;
  Color3 c3 = Color3::Green;
  printf("c1 = %d, c2 = %d, c3 = %d\n", c1, static_cast<int>(c2),
         static_cast<int>(c3));
}

void use_enum2() {
  Color2 c2 = Color2::Blue;
  switch (c2) {
    using enum Color2;
  case Red: {
    printf("Red\n");
  } break;
  case Green: {
    printf("Green\n");
  } break;
  case Blue: {
    printf("Blue\n");
  } break;
  default: {
    printf("Unknown color\n");
  }
  }
}

void pod_use() {
  Book b1{"圣经", 2024, 100};
  // 下面输出是 60 而不是 58, 因为 4 字节对齐
  printf("POD Book size = %lu\n", sizeof(Book));
  printf("title = %s, pages = %d, year = %d\n", b1.title, b1.pages, b1.year);
}

void union_use() {
  Variant v1;
  printf("Size of Variant: %lu\n", sizeof(v1));
  v1.i = 10;
  printf("v1.i = %d\n", v1.i);
  printf("v1.d = %g\n", v1.d);
  v1.d = 3.14;
  printf("v1.i = %d\n", v1.i);
  printf("v1.d = %g\n", v1.d);
}
